<?php

/**
 * RaiseTestPanel class
 * represents a RaiseTest GUI Panel
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @final
 * @package Raise.UnitTest
 * @version 1.4
 */
final class RaiseTestPanel {

    /**
     * An array containing all the tests
     * @var array
     * @static
     */
    private static $tests = array();

    /**
     * An array containing all the errors
     * @var array
     * @static
     */
    private static $errors = array();

    /**
     * Initialize and load all the unit tests
     * @static
     */
    private static function initialize(){
        error_reporting(E_ALL);

        // include the other two class
        include('RaiseTest.php');
        include('RaiseTestResult.php');

        $files = glob('units/*.[pP][hH][pP]', GLOB_NOSORT);
        foreach($files as $file){
            if(file_exists($file) && is_file($file)){
                include_once($file);
                $file = basename($file);
                $class = pathinfo($file, PATHINFO_FILENAME);
                if(class_exists($class, false) && is_subclass_of($class, 'RaiseTest')){
                    self::$tests[] = $class;
                }else{
                    self::$errors[] = 'Class ' . $class . ' not found or not subclass of RaiseTest.';
                }
            }
        }
        unset($files);
        $files = glob('mocks/*.php', GLOB_NOSORT);
        foreach($files as $file){
            if(file_exists($file) && is_file($file)){
                include_once($file);
            }
        }
    }

    private static function svnRevision(){
        $f = '.svn/entries';
        if(file_exists($f)){
            $d = file($f);
            return array_key_exists(3, $d) && $d[3] ? $d[3] : 'Failed to retrieve';
        }else{
            return $f . ' not found.';
        }
    }

    /**
     * Fetch and prepare the server information section
     * @return string
     * @static
     */
    private static function serverInfo(){
        $buffer = '';
        $buffer .= '<div class="info"><div class="label">PHP Version</div>'.  phpversion() . '</div>';
        $buffer .= '<div class="info"><div class="label">phpRaise Framework Version</div>'.  Raise::version() . '</div>';
        $buffer .= '<div class="info"><div class="label">RaiseTestPanel Version</div>'.  file_get_contents('VERSION') . '</div>';
        $buffer .= '<div class="info"><div class="label">SVN Revision</div>'.  self::svnRevision() . '</div>';
        $buffer .= '<div class="info"><div class="label">Operating System</div>' . php_uname('s') . ' ' . php_uname('r') . ' ' . php_uname('v').' ' . php_uname('m') . '</div>';
        $buffer .= '<div class="info"><div class="label">Host Name</div>'.  php_uname('n') . '</div>';
        $buffer .= '<div class="info"><div class="label">Server/PHP Interface</div>' . php_sapi_name() . '</div>';
        $buffer .= '<div class="info"><div class="label">Zend Version</div>' . zend_version() . '</div>';
        $buffer .= '<div class="info"><div class="label">PHP Config File</div>' . php_ini_loaded_file() . '</div>';
        $buffer .= '<div class="info"><div class="label">PHP Process ID</div>' . getmypid() . '</div>';
        $buffer .= '<div class="info"><div class="label">Server Date/Time (gmdate / date)</div>' . gmdate('jS M Y H:i:sa') . ' / ' . date('jS M Y H:i:sa') . '</div>';
        $buffer .= '<div class="info"><div class="label">Current Working Directory</div>' . getcwd() . '</div>';

        $dir = self::dirsize('../phpRaise');

        $buffer .= '<div class="info"><div class="label">phpRaise Size</div>' . number_format($dir['size'], 0, '.', ', ') . ' bytes</div>';
        $buffer .= '<div class="info"><div class="label">Total Files</div>' . number_format($dir['howmany'], 0, '.', ', ') . '</div>';
        return $buffer;
    }

    /**
     * Calculate the directory size
     * @param string $dir The path to the directory to calculate
     * @return array The result of an array of (size, howManyFiles)
     * @static
     */
    private static function dirsize($dir) {
	if(is_file($dir)){
            return array('size' => filesize($dir), 'howmany' => 0);
        }
	if(($dh=opendir($dir))) {
		$size=0;
		$n = 0;
		while(($file = readdir($dh)) !== false) {
			if($file == '.' || $file == '..'){ continue; }
			$n++;
			$data = self::dirsize($dir . '/' . $file);
			$size += $data['size'];
			$n += $data['howmany'];
		}
		closedir($dh);
		return array('size' => $size, 'howmany' => $n);
	}
	return array('size' => 0, 'howmany' => 0);
    }


    /**
     * Prepare the output and run the tests
     * @static
     */
    public static function run(){
        self::initialize();
        $outputBuffer = '';
        $version = file_get_contents('VERSION');
        $outputBuffer .= '<!DOCTYPE html>
            <html><head><title>RaiseTestPanel v' . $version . '</title>' . self::cssCode() . '</head>';
        $outputBuffer .= '<body><div class="container">' . self::headerImage() . '<div class="header">RaiseTestPanel v' . $version . '<div class="sub">Automated Testing for <a href="http://code.google.com/p/phpraise" target="_blank">phpRaise</a> by <a href="http://twitter.com/thephpdeveloper" target="_blank">Sam-Mauris Yong</a><br />Source code licensed under <a href="http://www.opensource.org/licenses/bsd-license" target="_blank">New BSD License</a></div></div><div class="entries">';
        $outputBuffer .= '<div class="sysinfo">' . self::serverInfo() . '</div>';

        $errors = '';
        foreach(self::$errors as $error){
            $errors .= self::formatError($error);
        }
        if($errors != ''){
            $errors = '<div class="header">Errors</div>' . $errors;
        }
        $outputBuffer .= $errors;

        $totalTest = 0;
        $successfulTest = 0;
        $totalTime = 0;
        foreach(self::$tests as $test){
            /** @var RaiseTestResult $result */
            $result = call_user_func(array($test, 'run'), $test);
            $outputBuffer .= self::formatResult($test, $result);

            $totalTime += $result->timeTaken;
            $totalTest += $result->totalTestCount;
            $successfulTest += $result->successfulTestCount;
        }

        $outputBuffer .= '<div class="final"><div style="float:right;">' . number_format($totalTime, 10) . 's</div>Total of ' . $successfulTest . ' / ' . $totalTest . ' tests ran successfully.</div>';

        $outputBuffer .= '</div>' . self::aboutRaiseTest() . '</div></body></html>';
        header('Set-Cookie: ', true);
        echo $outputBuffer;
    }

    /**
     * Format a message output
     * @param string $message The message
     * @return string
     * @static
     */
    private static function formatMessage($message){
        return '<div class="entry_message">' . self::prepareMessage($message) . '</div>';
    }

    /**
     * Format a error output
     * @param string $error The error
     * @return string
     * @static
     */
    private static function formatError($error){
        return '<div class="entry_error">' . self::prepareMessage($error) . '</div>';
    }

    /**
     * Format a warning output
     * @param string $warning The warning
     * @return string
     * @static
     */
    private static function formatWarning($warning){
        return '<div class="entry_warning">' . self::prepareMessage($warning) . '</div>';
    }

    /**
     * Prepare a message for formatting by disabling HTML and converting new lines to breaklines
     * @param string $s
     * @return string
     * @static
     */
    private static function prepareMessage($s){
        return nl2br(str_replace(array('<','>'),array('&lt;','&gt;'),$s));
    }

    /**
     * Format the result of a test
     * @param string $className The class name of the test
     * @param RaiseTestResult $result The result associated with the test
     * @return string
     * @static
     */
    private static function formatResult($className, $result){
        $messages = '';
        $errors = '';
        $warnings = '';

        $summary = '<div class="summary"' . ($result->successfulTestCount == $result->totalTestCount ? '' : ' style="background:#900;"') . '><div style="float:right;">' . number_format($result->timeTaken, 10) . 's<br />' . $result->memoryUse . ' bytes</div><div class="name">' . $className . '</div>';
        $summary .= '<div class="result"><b>' . $result->successfulTestCount . ' / ' . $result->totalTestCount . '</b> tests ran successfully</div></div>';

        foreach($result->errors as $error){
            $errors .= self::formatError($error);
        }

        if($errors != ''){
            $errors = '<div class="header">Errors</div>' . $errors;
        }

        foreach($result->warnings as $warning){
            $warnings .= self::formatWarning($warning);
        }
        if($warnings != ''){
            $warnings = '<div class="header">Warnings</div>' . $warnings;
        }
        foreach($result->messages as $message){
            $messages .= self::formatMessage($message);
        }
        if($messages != ''){
            $messages = '<div class="header">Messages</div>' . $messages;
        }


        return '<div class="resultset">' . $summary . $errors . $warnings . $messages . '</div>';
    }

    /**
     * Get the About entity
     * @return string
     * @static
     */
    private static function aboutRaiseTest() {
        return '<div id="ftr"><a href="#" id="abtLink">About RaiseTestPanel</a>
            <div id="abtTxt"><a href="#" id="abtCloseLink">[Close]</a><div class="header">About RaiseTestPanel
            <div class="sub">Automated Testing for <a href="http://code.google.com/p/phpraise" target="_blank">phpRaise</a> by <a href="http://twitter.com/thephpdeveloper" target="_blank">Sam-Mauris Yong</a><br />Source code licensed under <a href="http://www.opensource.org/licenses/bsd-license" target="_blank">New BSD License</a></div></div>
            <p>The RaiseTestPanel sub-project started when Sam was developing phpRaise, and he could not find a suitable, up-to-date and well-documented automated testing tool for phpRaise.</p>
            <p>When developing RaiseTestPanel, the following factors were considered:</p>
            <ul><li>The independence of the testing tool from the phpRaise framework. The tool should not rely on the phpRaise framework for its operations.</li>
            <li>The responsive feedback for the tester (including at which file and line did the error occurred, call stack and so on).</li>
            <li>Tracking and managing the time taken for the tests to be completed.</li></ul>
            <p>Automated Regression Testing becomes easy with RaiseTestPanel because whenever you run the tool, all tests ran together and you just have to keep incrementing the tests.</p>
            <p>The testing tool is very lightweight (less than 50kb), fast (optimized OOP usage) and easy to use (testings are all automated).</p>
            </div></div>
            <script type="text/javascript">/* <![CDATA[ */ document.getElementById("abtLink").style.display = "block"; document.getElementById("abtTxt").style.display = "none"; document.getElementById("abtCloseLink").style.display = "block"; document.getElementById("abtCloseLink").onclick = function(){document.getElementById("abtTxt").style.display = "none"; document.getElementById("abtLink").style.display = "block"; return false;}; document.getElementById("abtLink").onclick = function(){document.getElementById("abtTxt").style.display = "block"; this.style.display = "none"; return false;} /* ]]> */</script>';
    }

    /**
     * Return the header image
     * @return string
     * @static
     */
    private static function headerImage(){
        return '<img style="float:right; width:200px; height:100px" src="
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
AAAASUVORK5CYII=" alt="RaiseTestPanel" />';
    }

    /**
     * Return the CSS code
     * @return string
     * @static
     */
    private static function cssCode(){
        return '<style type="text/css"><!--
            body{font:normal 12px/1.6 Tahoma}a:visited,a{font-family:Lucida Sans;text-decoration:none;color:#EB0}a:hover{text-decoration:underline;color:#FC3}.container{width:630px;margin:20px auto 100px}.header{font:bold 25px Lucida Sans;margin-bottom:10px;color:#666;height:90px}.header,.header .sub{margin-left:10px}.header .sub{font:normal 11px/2.2 Verdana;margin-top:5px;color:#AAA;border-left:5px solid #EEE;background:#f6f6f6;margin-right:30px}.header .sub,.entries .header{padding-left:10px}.entries,.entries .sysinfo .info:hover{background:#EEE}.entries,.entries .sysinfo,.entries .sysinfo .info,.entries .header,.entries .summary,#ftr{padding:5px}.entries,.entries .sysinfo .info{clear:both}.entries .resultset{text-shadow:1px 1px 3px #555}.entries .sysinfo{width:600px;margin:5px auto;background:#FFF}.entries .sysinfo .info{text-align:right;border-bottom:1px solid #EEE}.entries .sysinfo .info .label{float:left;color:#888}.entries .header{font:16px Tahoma;color:#222;height:auto}.entries .name{font:18px Tahoma}.entries .entry_warning,.entries .entry_message,.entries .entry_error,.entries .final{padding:5px 10px}.entries .entry_warning,.entries .entry_message,.entries .entry_error{margin:5px 20px;border-left:5px solid #CCC}.entries .entry_error{background:#A00}.entries .entry_error,.entries .entry_message,.entries .entry_warning,.entries .summary{color:#FFF}.entries .entry_message{background:#999}.entries .entry_warning{background:#EA1}.entries .summary{margin:5px;background:#666}.entries .final{color:#333;text-shadow:1px 1px 0 #FFF}#ftr{border:5px solid #EEE}#abtLink,#abtCloseLink{display:none}#abtCloseLink{float:right;}
            --></style>';
    }

}
